<template>
	<view>
		<!-- 需要截图的容器 添加ID -->
		<view id="shareCare" class="shareCare">
			<!-- 原有结构保持不变 -->
		</view>
		<view class="saveText" @click="saveToImage">保存到相册</view>
	</view>
</template>

<script>
	// H5端需要先安装 html2canvas：npm install html2canvas
	// 小程序端需要配置 manifest.json 添加 "requiredBackgroundModes": ["canvas"]
	export default {
		methods: {
			async saveToImage() {
				// #ifdef H5
				const html2canvas = await import('html2canvas')
				const element = document.getElementById('shareCare')

				html2canvas
					.default(element, {
						useCORS: true, // 解决跨域图片
						scale: 2, // 提高分辨率
						backgroundColor: null // 透明背景
					})
					.then((canvas) => {
						const imgUrl = canvas.toDataURL('image/png')
						this.saveImage(imgUrl)
					})
				// #endif

				// #ifdef MP-WEIXIN
				const query = uni.createSelectorQuery().in(this)
				query
					.select('#shareCare')
					.boundingClientRect(async (rect) => {
						const systemInfo = await uni.getSystemInfoSync()
						const dpr = systemInfo.pixelRatio

						const ctx = uni.createCanvasContext('shareCanvas', this)

						// 设置 canvas 尺寸（需要考虑DPI）
						ctx.canvasWidth = rect.width * dpr
						ctx.canvasHeight = rect.height * dpr
						ctx.scale(dpr, dpr)

						// 绘制背景（根据实际样式调整）
						ctx.setFillStyle('#ffffff')
						ctx.fillRect(0, 0, rect.width, rect.height)

						// 递归绘制子元素
						await this.drawChildren(ctx, '#shareCare', 0, 0)

						ctx.draw(false, () => {
							uni.canvasToTempFilePath({
								canvasId: 'shareCanvas',
								success: (res) => {
									this.saveImage(res.tempFilePath)
								}
							})
						})
					})
					.exec()
				// #endif
			},

			// 通用保存方法
			saveImage(url) {
				// #ifdef H5
				const link = document.createElement('a')
				link.download = 'share.png'
				link.href = url
				link.click()
				// #endif

				// #ifdef MP-WEIXIN
				uni.saveImageToPhotosAlbum({
					filePath: url,
					success: () => uni.showToast({ title: '保存成功' }),
					fail: () => uni.showToast({ title: '保存失败' })
				})
				// #endif
			},

			// 小程序端递归绘制元素
			async drawChildren(ctx, selector, offsetX, offsetY) {
				const query = uni.createSelectorQuery().in(this)
				return new Promise((resolve) => {
					query
						.select(selector)
						.boundingClientRect(async (rect) => {
							// 绘制当前元素背景
							if (rect.backgroundColor) {
								ctx.setFillStyle(rect.backgroundColor)
								ctx.fillRect(offsetX, offsetY, rect.width, rect.height)
							}

							// 处理子元素
							const nodes = await this.getChildNodes(selector)
							for (const node of nodes) {
								if (node.tagName === 'IMAGE') {
									await this.drawImage(ctx, node, offsetX, offsetY)
								} else if (node.textContent) {
									this.drawText(ctx, node, offsetX, offsetY)
								}
							}
							resolve()
						})
						.exec()
				})
			},

			// 绘制图片
			async drawImage(ctx, node, parentX, parentY) {
				return new Promise((resolve) => {
					uni.downloadFile({
						url: node.src,
						success: (res) => {
							ctx.drawImage(res.tempFilePath, parentX + node.left, parentY + node.top, node.width, node.height)
							resolve()
						}
					})
				})
			},

			// 绘制文本
			drawText(ctx, node, parentX, parentY) {
				ctx.setFontSize(node.fontSize)
				ctx.setFillStyle(node.color)
				ctx.fillText(node.textContent, parentX + node.left, parentY + node.top + node.height / 2)
			},

			// 获取子节点信息
			getChildNodes(selector) {
				return new Promise((resolve) => {
					const query = uni.createSelectorQuery().in(this)
					query
						.select(selector)
						.fields(
							{
								node: true,
								size: true,
								rect: true,
								computedStyle: ['color', 'fontSize', 'backgroundColor']
							},
							(res) => {
								resolve(res.node.childNodes || [])
							}
						)
						.exec()
				})
			}
		}
	}
</script>

<style>
	/* 添加 canvas 样式（小程序需要） */
	#shareCanvas {
		position: fixed;
		left: 9999px;
		top: 9999px;
	}
</style>
